import {getDomain} from "../request.js";
import {uploadInit, handlerBtn, clearFiles, setHeaders} from "./layui-upload-common.js";
import {sheet} from "./layui-upload-sheet.js";

export let uploadApi = {
    // 上传组件
    upload: {},

    /**
     * 获取回调方法操作，图片和视频（完全兼容），其他格式需自定义覆盖方法
     *
     * @param config
     * @param initConfig
     * @returns {{uploadBox: (*|Array|jQuery), resetResource(): void, init(): void, handlerResource(*=, *=, *=): void, choose(*, *, *=): void, uploadDom: string, label: string, done(*): void}}
     */
    getCallback(config, initConfig) {
        return {

            // 资源展示的选择器
            uploadDom: '.layui-upload-list',

            // 资源容器
            uploadBox: $(config.resetAction).nextAll(this.customize),

            // 资源标签
            label: '',

            /**
             * 初始化图片资源模块
             */
            init() {
                // 展示相关资源模板
                let isShow = typeof initConfig.resource != 'undefined' && Object.keys(initConfig.resource).length != 0 ? true : false;

                this.handlerResource(initConfig.resource.url, initConfig.resource.input, isShow);
            },

            /**
             * 处理资源模板
             *
             * @param resource  资源值
             * @param val       input值
             * @param isShow    是否显示
             */
            handlerResource(resource, val, isShow) {
                // 图片设置 和 清空input
                this.uploadBox.find(this.label).attr('src', resource);
                this.uploadBox.find('input').val(val);

                // 是否显示资源模块
                this.uploadBox.hide();
                if (isShow) this.uploadBox.show();
            },

            /**
             * 选择文件触发回调
             *
             * @param index
             * @param file
             * @param result
             */
            choose(index, file, result) {
                // 显示当前资源模块
                this.handlerResource(result, '', true);
            },

            /**
             * 重置按钮触发回调函数
             */
            resetResource() {
                // 隐藏当前资源模块
                this.handlerResource('', '', false);
            },

            /**
             * 回调触发函数
             *
             * @param result
             */
            done(result) {
                // 更改input
                this.uploadBox.find('input').val(result.code == 200 ? result.data.input : '');

                // 自定义回调方法
                if (typeof initConfig.callback != 'undefined') initConfig.callback(result);
            }
        }
    },

    /**
     * 渲染图片组件
     *
     * @param config
     * @param initConfig
     */
    image(config = {}, initConfig = {}) {
        // 自定义配置
        let customize = {

            // 组件配置
            config: {
                field: 'img',
                size: 2048,
                accept: 'images',
                acceptMime: 'image/png,image/jpg,image/jpeg',

                ...config
            },

            // 个性化配置
            customize: {
                // 回调操作
                ...this.getCallback(config, initConfig),

                // 资源标签
                label: 'img',

            }

        };

        // 渲染上传组件
        this.render(customize, initConfig, 'upload-img');
    },

    /**
     * 渲染视频组件
     *
     * @param config
     * @param initConfig
     */
    video(config = {}, initConfig = {}) {
        // 自定义配置
        let customize = {

            // 组件配置
            config: {
                field: 'video',
                size: 20480,
                accept: 'video',
                acceptMime: 'video/mp4,video/webm,video/ogg',

                ...config
            },

            // 个性化配置
            customize: {

                // 回调操作
                ...this.getCallback(config, initConfig),

                // 资源标签
                label: 'video',

            }

        };

        // 渲染上传组件
        this.render(customize, initConfig, 'upload-video');
    },

    /**
     * 渲染文件组件
     *
     * @param config
     * @param initConfig
     */
    file(config = {}, initConfig = {}) {
        // 自定义配置
        let customize = {

            // 组件配置
            config: {
                field: 'file',
                size: 20480,
                accept: 'file',
                acceptMime: 'video/*,image/*',

                ...config
            },

            // 个性化配置
            customize: {

                // 回调操作
                ...this.getCallback(config, initConfig),

                // 资源标签
                label: 'span',

                /**
                 * 选择文件触发回调
                 *
                 * @param index
                 * @param file
                 * @param result
                 */
                choose(index, file, result) {
                    // 显示当前资源模块
                    this.handlerResource(file.name, '', true);
                },

                /**
                 * 处理资源模板
                 *
                 * @param resource  图片链接
                 * @param val       input值
                 * @param isShow    是否显示
                 */
                handlerResource(resource, val, isShow) {
                    // 文本设置 和 清空input
                    this.uploadBox.find(this.label).text(resource);
                    this.uploadBox.find('input').val(val);

                    // 是否显示资源模块
                    this.uploadBox.hide();
                    if (isShow) this.uploadBox.show();
                },

            }

        };

        // 渲染上传组件
        this.render(customize, initConfig, 'upload-file');
    },

    /**
     * 渲染组件
     *
     * @param config        额外配置
     * @param initConfig    初始化配置
     * @param url           请求url
     */
    render(config, initConfig, url) {
        // 初始化操作
        uploadInit(config, initConfig);

        // 上传组件渲染
        uploadApi.upload.render({
            url: getDomain() + url,
            auto: false,

            // 额外属性
            customize: {
                files: {},
                load: false,
            },

            // 重置按钮
            resetAction: '',

            /**
             * 选择文件触发操作
             *
             * @param obj
             */
            choose(obj) {
                // 清除File
                clearFiles(this.customize.files);

                // 添加文件
                this.customize.files = obj.pushFile();

                // 清空file下的value，避免不可重复上传资源
                $(this.elem).next().val('');

                // 预览资源
                for (let i in this.customize.files) {
                    // 按钮显示并处理
                    handlerBtn(this, true);

                    // 触发自定义回调
                    config.customize.choose(i, this.customize.files[i], URL.createObjectURL(this.customize.files[i]));
                }

                // 是否分片上传
                if (typeof config.config.sheet !== 'undefined' && config.config.sheet) sheet(config, this);

                // 重置资源，取消绑定事件
                if (typeof $._data($(this.resetAction)[0], 'events') != 'undefined') $(this.resetAction).unbind();

                $(this.resetAction).one('click', () => {
                    // 隐藏按钮 和 更改文字
                    handlerBtn(this, false);

                    // 隐藏当前资源模块
                    config.customize.resetResource();

                    // 清空file下的value，避免不可重复上传资源
                    $(this.elem).next().val('');

                    // 清除File
                    clearFiles(this.customize.files);
                });
            },

            /**
             * 上传前触发回调
             */
            before() {
                // 设置header头
                this.headers = setHeaders();

                // 启用加载层
                this.customize.load = layer.load(2);
            },

            /**
             * 正常回调
             *
             * @param res
             * @param index
             * @returns {Promise<void>}
             */
            done: async function (res, index) {
                // 替换token
                await resetToken();

                // 关闭 加载层
                layer.close(this.customize.load);

                // 触发自定义函数
                config.customize.done(res);

                // 验证回调
                if (res.code === 200) {
                    // 隐藏开始上传按钮
                    this.bindAction.hide();

                    // 上传成功则删除文件对象
                    delete this.customize.files[index];
                } else {
                    this.bindAction.text('重新上传');
                }

                //  弹出请求内容
                dialog(res.code === 200 ? res.msg : (res.msg ? res.msg : '文件上传失败'));
            },

            /**
             * 错误回调
             *
             * @param index
             * @param upload
             */
            async error(index, upload) {
                // 关闭 加载层
                layer.close(this.customize.load);

                // 重新上传
                this.bindAction.text('重新上传');

                dialog('当前网络较差，请稍候尝试');
            },

            // 自定义配置项
            ...config.config,
        });
    },
};
